import Ipha_tool from "../Ipha_tool";
import Ipha_ComponentBasic from "./Ipha_ComponentBasic";

const { ccclass, property, menu, executeInEditMode } = cc._decorator;

enum alignment {
    left,
    right,
    top,
    bottom,
    horizontalCenter,
    verticalCenter,
}

enum useType {
    none,
    alignment,
    distance,
}

/**
 * 节点关联对齐组件
 */
@ccclass
@executeInEditMode
@menu("ipha组件/节点关联对齐组件")
export default class Ipha_Correlation extends Ipha_ComponentBasic {

    comName: string = "节点关联对齐组件";

    @property({ type: cc.Node, displayName: "目标节点" })
    private ndTarget: cc.Node = null;

    @property({ type: cc.Enum(useType), displayName: "使用模式", tooltip: "空\n对齐\n间隔" })
    private type: useType = useType.none;

    //  alignment  对齐相关属性

    @property({ displayName: "左对齐", visible() { return this.type == useType.alignment && !this.verticalCenter } })
    private left: boolean = false;
    @property({ displayName: "左对齐偏差", visible() { return this.type == useType.alignment && this.left } })
    private leftOffset: number = 0;
    @property({ displayName: "右对齐", visible() { return this.type == useType.alignment && !this.verticalCenter } })
    private right: boolean = false;
    @property({ displayName: "右对齐偏差", visible() { return this.type == useType.alignment && this.right } })
    private rightOffset: number = 0;
    @property({ displayName: "顶对齐", visible() { return this.type == useType.alignment && !this.horizontalCenter } })
    private top: boolean = false;
    @property({ displayName: "顶对齐偏差", visible() { return this.type == useType.alignment && this.top } })
    private topOffset: number = 0;
    @property({ displayName: "底对齐", visible() { return this.type == useType.alignment && !this.horizontalCenter } })
    private bottom: boolean = false;
    @property({ displayName: "底对齐偏差", visible() { return this.type == useType.alignment && this.bottom } })
    private bottomOffset: number = 0;

    @property({ displayName: "水平居中", visible() { return this.type == useType.alignment && !this.top && !this.bottom } })
    private horizontalCenter: boolean = false;
    @property({ displayName: "水平居中偏差", visible() { return this.type == useType.alignment && this.horizontalCenter } })
    private horizontalCenterOffset: number = 0;
    @property({ displayName: "竖直居中", visible() { return this.type == useType.alignment && !this.left && !this.right } })
    private verticalCenter: boolean = false;
    @property({ displayName: "竖直居中偏差", visible() { return this.type == useType.alignment && this.verticalCenter } })
    private verticalCenterOffset: number = 0;


    // distance  保持间隔相关属性

    @property({ displayName: "于左间隔", visible() { return this.type == useType.distance && !this.rightD } })
    private leftD: boolean = false;
    @property({ displayName: "于左间隔偏差", visible() { return this.type == useType.distance && this.leftD } })
    private leftDOffset: number = 0;
    @property({ displayName: "于右间隔", visible() { return this.type == useType.distance && !this.leftD } })
    private rightD: boolean = false;
    @property({ displayName: "于右间隔偏差", visible() { return this.type == useType.distance && this.rightD } })
    private rightDOffset: number = 0;
    @property({ displayName: "于顶间隔", visible() { return this.type == useType.distance && !this.bottomD } })
    private topD: boolean = false;
    @property({ displayName: "于顶间隔偏差", visible() { return this.type == useType.distance && this.topD } })
    private topDOffset: number = 0;
    @property({ displayName: "于底间隔", visible() { return this.type == useType.distance && !this.topD } })
    private bottomD: boolean = false;
    @property({ displayName: "于底间隔偏差", visible() { return this.type == useType.distance && this.bottomD } })
    private bottomDOffset: number = 0;

    private _isRun: boolean = true;
    get isRun() { return this._isRun; }
    set isRun(bool: boolean) { this._isRun = bool; }

    private _isAlignment: boolean = true;
    get isAlignment() { return this._isAlignment; }
    set isAlignment(bool: boolean) { this._isAlignment = bool; }

    private _isDistance: boolean = true;
    get isDistance() { return this._isDistance; }
    set isDistance(bool: boolean) { this._isDistance = bool; }

    setTarget(targetNode: cc.Node) {
        this.ndTarget = targetNode;
    }

    onLoad() {
        if (this.ndTarget == null) {
            this.ndTarget = this.node?.parent;
        }
    }

    start() {
        if (this._isRun && this.ndTarget) {
            if (this.ndTarget.activeInHierarchy) {
                this.alignment();
                this.distance();
            } else {
                this.node.setPosition(cc.v2(0, 0));
            }
        }
    }

    alignment() {
        if (this.type != useType.alignment || !this._isAlignment) { return; }

        let pos = Ipha_tool.pos.rootPosToTargetNodeSpace(this.ndTarget, this.node.parent);

        // 左右对齐
        if (this.left && this.right) {
            let targetLeft = pos.x - (this.ndTarget.width * this.ndTarget.scaleX * this.ndTarget.anchorX) + this.leftOffset;
            let targetRight = pos.x + (this.ndTarget.width * this.ndTarget.scaleX * (1 - this.ndTarget.anchorX)) - this.rightOffset;
            this.node.width = Math.abs(targetRight - targetLeft);
            this.node.x = targetLeft + (this.node.width * this.ndTarget.scaleX * this.node.anchorX);
        } else if (this.left) {
            let targetLeft = pos.x - (this.ndTarget.width * this.ndTarget.scaleX * this.ndTarget.anchorX);
            this.node.x = targetLeft + (this.node.width * this.ndTarget.scaleX * this.node.anchorX) + this.leftOffset;
        } else if (this.right) {
            let targetRight = pos.x + (this.ndTarget.width * this.ndTarget.scaleX * (1 - this.ndTarget.anchorX));
            this.node.x = targetRight - (this.node.width * this.ndTarget.scaleX * (1 - this.node.anchorX)) - this.rightOffset;
        } else if (this.verticalCenter) {
            let targetLeft = pos.x - (this.ndTarget.width * this.ndTarget.scaleX * this.ndTarget.anchorX);
            let targetCenter = targetLeft + (this.ndTarget.width * this.ndTarget.scaleX * 0.5);
            this.node.x = targetCenter - (this.node.width * this.ndTarget.scaleX * (0.5 - this.node.anchorX)) + this.verticalCenterOffset;
        }

        // 顶底对齐
        if (this.top && this.bottom) {
            let targetTop = pos.y + (this.ndTarget.height * this.ndTarget.scaleY * (1 - this.ndTarget.anchorY)) - this.topOffset;
            let targetBottom = pos.y - (this.ndTarget.height * this.ndTarget.scaleY * this.ndTarget.anchorY) + this.bottomOffset;
            this.node.height = targetTop - targetBottom;
            this.node.y = targetBottom + (this.node.height * this.ndTarget.scaleY * this.node.anchorY);
        } else if (this.top) {
            let targetTop = pos.y + (this.ndTarget.height * this.ndTarget.scaleY * (1 - this.ndTarget.anchorY)) - this.topOffset;
            this.node.y = targetTop - (this.node.height * this.ndTarget.scaleY * (1 - this.node.anchorY));
        } else if (this.bottom) {
            let targetBottom = pos.y - (this.ndTarget.height * this.ndTarget.scaleY * this.ndTarget.anchorY) + this.bottomOffset;
            this.node.y = targetBottom + (this.node.height * this.ndTarget.scaleY * this.node.anchorY);
        } else if (this.horizontalCenter) {
            let targetBottom = pos.y - (this.ndTarget.height * this.ndTarget.scaleY * this.ndTarget.anchorY);
            let targetCenter = targetBottom + (this.ndTarget.height * this.ndTarget.scaleY * 0.5);
            this.node.y = targetCenter - (this.node.height * this.ndTarget.scaleY * (0.5 - this.node.anchorY)) + this.horizontalCenterOffset;
        }
    }

    distance() {
        if (this.type != useType.distance || !this._isDistance) { return; }

        let pos = Ipha_tool.pos.rootPosToTargetNodeSpace(this.ndTarget, this.node.parent);

        if (this.leftD) {
            let targetLeft = pos.x - (this.ndTarget.width * this.ndTarget.scaleX * this.ndTarget.anchorX);
            this.node.x = targetLeft - (this.node.width * this.ndTarget.scaleX * (1 - this.node.anchorX) + this.leftDOffset);
        } else if (this.rightD) {
            let targetRight = pos.x + (this.ndTarget.width * this.ndTarget.scaleX * (1 - this.ndTarget.anchorX));
            this.node.x = targetRight + (this.node.width * this.ndTarget.scaleX * this.node.anchorX + this.rightDOffset);
        }

        if (this.topD) {
            let targetTop = pos.y + (this.ndTarget.height * this.ndTarget.scaleY * (1 - this.ndTarget.anchorY));
            this.node.y = targetTop + (this.node.height * this.ndTarget.scaleY * this.node.anchorY + this.topDOffset);
        } else if (this.bottomD) {
            let targetBottom = pos.y - (this.ndTarget.height * this.ndTarget.scaleY * this.ndTarget.anchorY);
            this.node.y = targetBottom - (this.node.height * this.ndTarget.scaleY * (1 - this.node.anchorY) + this.bottomDOffset);
        }
    }

    _RunTheCorrelation() {
        if (this.ndTarget) {
            if(this.ndTarget.activeInHierarchy) {
                this.alignment();
                this.distance();
            } else {
                this.node.setPosition(cc.v2(0, 0));
            }
        }
    }

    protected update(dt: number): void {
        if (this._isRun) {
            this._RunTheCorrelation();
        }
    }
}
